from django.db import transaction
from rest_framework import serializers
from goods.models import SKU, SKUSpecification
from celery_tasks.detail.tasks import generate_detail_html  ## ?? 前面什么时候用加meiduo_mall.


class SkuSpecSerializer(serializers.Serializer):
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()


class SkuSerializer(serializers.ModelSerializer):
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    category = serializers.StringRelatedField(read_only=True)
    category_id = serializers.IntegerField()
    specs = SkuSpecSerializer(many=True)  ## 因为要输入，所以把只读去掉了

    class Meta:
        model = SKU
        fields = '__all__'

    def create(self, validated_data):  ## validated_data 字典形式
        specs = validated_data.pop('specs')
        with transaction.atomic():
            sid = transaction.savepoint()
            try:
                # 1.保存sku
                sku = super().create(validated_data)

                # 2.保存规格信息
                for item in specs:
                    item['sku_id'] = sku.id
                    item = SKUSpecification.objects.create(**item)
            except:
                transaction.savepoint_rollback(sid)  ## 先回滚再抛出异常
                raise serializers.ValidationError('创建失败')


            else:
                transaction.savepoint_commit(sid)

                # 静态化
                generate_detail_html.delay(sku.id)
                return sku

    def update(self, instance, validated_data):
        specs = validated_data.pop('specs')
        with transaction.atomic():
            sid = transaction.savepoint()
            try:
                # 修改sku对象
                instance = super().update(instance, validated_data)  ## self？

                SKUSpecification.objects.filter(sku_id=instance.id).delete()  ## 注意instance.id
                ##  ?? 删除时查chu多个直接能一次delete? keyi
                for item in specs:
                    item['sku_id'] = instance.id  ## instance
                    SKUSpecification.objects.create(**item)
            except:
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError('修改sku 失败')

            else:
                transaction.savepoint_commit(sid)

                generate_detail_html.delay(instance.id)  ##  第一次可能执行不成功，因为上面事务操作耗时，可能在执行任务时，sku还没有保存成功
                return instance


class SkuSimpleSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True) ## 为什么t 没写只读
    name = serializers.CharField()
